package net.kesumu.yushabu;

import java.net.URI;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;

import net.kesumu.general.android.EasyStorage.EasyStorage;
import net.kesumu.general.android.view.CustomStatusBar;
import net.kesumu.yushabu.storage.FriendDbOperator;
import net.kesumu.yushabu.storage.YushabuMessageContract;
import net.kesumu.yushabu.utils.JSONUtil;
import net.kesumu.yushabu.utils.WsConfig;
import net.kesumu.yushabuserver.entity.User;
import net.kesumu.yushabuserver.entity.YushabuMessage;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ListFragment;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.codebutler.android_websockets.WebSocketClient;
import com.umeng.message.PushAgent;

import net.kesumu.yushabu.R;

public class GroupChatActivity extends Activity {
    
    private EasyStorage mEasyStorage;
    
    String mMyId;
    
    ArrayList<User> mFriendList;
    FriendAdapter mFriendAdapter;
    
    //Up to now, this app setting to only support 5 persons' group chat
    public static final int GROUP_CHAT_MAX_NUMBER = 5;
    ArrayList<User> mSelectedFriendList = new ArrayList<User>();
    ArrayList<ImageView> mSelectedFriendPhotoList = new ArrayList<ImageView>();
    
    ProgressDialog prgDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_chat);
        getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 
        getActionBar().setCustomView(R.layout.actionbar);
        ((TextView)findViewById(R.id.actionbar_title)).setText(getString(R.string.title_activity_group_chat));
      //Custom the status bar
        CustomStatusBar customStatusBar = new CustomStatusBar(this);
        customStatusBar.setStatusBarColor(findViewById(R.id.statusBarBackground), getResources().getColor(R.color.main));


        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FriendFragment()).commit();
        }
        
        mEasyStorage = new EasyStorage(this, getString(R.string.preference_file_key));
        mMyId = mEasyStorage.getString("mMyId");
        
        startUpClient();
        
        prgDialog = new ProgressDialog(this);
        // Set Cancelable as False
        prgDialog.setCancelable(false);
        
        PushAgent.getInstance(this).onAppStart();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.group_chat, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_startGroupChat) {
            startGroupChat();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    void startGroupChat() {
        prgDialog.setMessage("Start group chat...");
        prgDialog.show();
        sendRequest(jsonUtil.getSetupMessageGroupJSON(mMyId, mSelectedFriendList));
    }
    
    private void readFriendListFromLocalDatabase() {
        LocalFriendListReader localFriendListReader = new LocalFriendListReader();
        localFriendListReader.execute("");
    }
    
    private class FriendAdapter extends BaseAdapter{
        
        ArrayList<User> friendList = new ArrayList<User>();
        
        public void setData(ArrayList<User> fl) {
            this.friendList.clear();
            if(fl == null) {
                return;
            }
            for(int i=0;i<fl.size();i++) {
                this.friendList.add(fl.get(i));
            }
            this.notifyDataSetChanged();
        }
        public int getCount() {
            if(friendList == null) {
                return 0;
            }else {
                return friendList.size();
            }
        }
        public Object getItem(int position) {
            if(friendList == null) {
                return null;
            }else{
                User friend = friendList.get(position);
                return friend;
            }
        }
        public long getItemId(int position) {
            return position;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
            User friend = (User)getItem(position);
            ViewGroup listView = null;
            
            listView = (ViewGroup)getLayoutInflater().inflate(R.layout.element_group_chat, null);
            TextView mFriendNameView = (TextView)listView.findViewById(R.id.text_name_friend);
            mFriendNameView.setText(friend.getName());
            TextView mFriendIdView = (TextView)listView.findViewById(R.id.text_id_friend);
            mFriendIdView.setText(friend.getUserId()+"");
            
            String friendYuYuChatId = friend.getYuyuChatId();
            //Remember this image view, then set downloaded image to it
            ImageView mFriendPhotoView = (ImageView) listView.findViewById(R.id.image_photo_friend);
            //Test whether this user's photo is stored on device, if not then download it
            String photoName = friendYuYuChatId;
            String photoExtention = "jpg";
            Bitmap photo = mEasyStorage.getImageBitmap(photoName, photoExtention);

            if(photo!=null) {
                //This photo is already saved
                mFriendPhotoView.setImageBitmap(photo);
            }
            
            CheckBox itemCheckBox = (CheckBox)(listView.findViewById(R.id.check_friendSelected));
            for(int i=0;i<mSelectedFriendList.size();i++) {
                if(friend.getUserId() == mSelectedFriendList.get(i).getUserId()) {
                    itemCheckBox.setChecked(true);
                }
            }
            
            
            /*String location = pixivPicture.location;
            if(location == null || location.length() == 0) {
              Toast.makeText(MainMenuActivity.this, "location error", Toast.LENGTH_SHORT).show();
              return null;
            }
            File imageFile = new File(location);
            if(!imageFile.exists()) {
                Toast.makeText(MainMenuActivity.this, "location file not found", Toast.LENGTH_SHORT).show();
                return null;
            }
            Bitmap bm = BitmapFactory.decodeFile(location);
            ImageView iv = (ImageView)listView.findViewById(R.id.picture_square);
            iv.setImageBitmap(bm);*/
            
            return listView;
        }
        
        public void addItem(final User item) {
            friendList.add(item);
            notifyDataSetChanged();
        }
    }
    
    /**
     * define the friend fragment for friend list
     * @author Z 2014-12-16
     *
     */
    @SuppressLint("ValidFragment")
    private class FriendFragment extends ListFragment {   
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View fragment = inflater.inflate(R.layout.fragment_group_chat, container, false);
            mFriendAdapter = new FriendAdapter();
            readFriendListFromLocalDatabase();
//            mFriendAdapter.addSeparatorItem(new User());
//            mFriendAdapter.addItem(new User(1, "itsuki"));
            setListAdapter(mFriendAdapter);            
            return fragment;
        }
        
        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            super.onListItemClick(l, v, position, id);
            int userId = Integer.parseInt(((TextView)v.findViewById(R.id.text_id_friend)).getText().toString());
            CheckBox itemCheckBox = (CheckBox)(v.findViewById(R.id.check_friendSelected));
            if(itemCheckBox.isChecked()) {
                itemCheckBox.setChecked(false);
                for(int i=0;i<mSelectedFriendList.size();i++) {
                    if(userId == mSelectedFriendList.get(i).getUserId()) {
                        ViewGroup selectedFriendContainer = (ViewGroup) findViewById(R.id.container_selectedFriend);
                        selectedFriendContainer.removeView(mSelectedFriendPhotoList.get(i));
                        HorizontalScrollView selectedFriendScrollView = (HorizontalScrollView) findViewById(R.id.scroll_selectedFriend);
                        selectedFriendScrollView.scrollTo(selectedFriendScrollView.getWidth(), 0);
                        mSelectedFriendList.remove(i);
                        mSelectedFriendPhotoList.remove(i);
                        break;
                    }
                }
                
            }else {
                if(mSelectedFriendList.size() == GROUP_CHAT_MAX_NUMBER-1) {
                    //Group chat number is full, not add more
                    showToast(getString(R.string.info_numberFull));
                }else {
                    itemCheckBox.setChecked(true);
                    User selectedFriend = new User();
                    selectedFriend.setUserId(userId);
                    mSelectedFriendList.add(selectedFriend);
                    
                    ImageView userPhoto = ((ImageView)v.findViewById(R.id.image_photo_friend));
                    ImageView selectFriendPhoto = (ImageView) LayoutInflater.from(GroupChatActivity.this).inflate(R.layout.photo_selected_friend, null);
                    int width = (int) getResources().getDimension(R.dimen.imageview_height);;
                    int height = (int) getResources().getDimension(R.dimen.imageview_width);;
                    LayoutParams parms = new LayoutParams(width,height);
                    selectFriendPhoto.setLayoutParams(parms);
                    selectFriendPhoto.setImageDrawable(userPhoto.getDrawable()); 
                    ViewGroup selectedFriendContainer = (ViewGroup) findViewById(R.id.container_selectedFriend);
                    selectedFriendContainer.addView(selectFriendPhoto);
                    mSelectedFriendPhotoList.add(selectFriendPhoto);
                    HorizontalScrollView selectedFriendScrollView = (HorizontalScrollView) findViewById(R.id.scroll_selectedFriend);
                    selectedFriendScrollView.scrollTo(selectedFriendScrollView.getWidth(), 0);
                }
            }
        }
    }
    
    private class LocalFriendListReader extends AsyncTask<String, Integer, ArrayList<User>>{
        @Override
        protected ArrayList<User> doInBackground(String... arg0) {
            FriendDbOperator friendDbOperator = new FriendDbOperator(getApplicationContext());
            return friendDbOperator.selectAll();
        }
        
        @Override
        protected void onPostExecute(ArrayList<User> result) {
            super.onPostExecute(result);
            mFriendList = result;
            mFriendAdapter.setData(mFriendList);
        }
        
    }
    
    
    @Override
    protected void onDestroy() {
        if(client != null && client.isConnected()) {
            client.disconnect();
            client = null;
        }
        // Dismiss the progress bar when application is closed
        if (prgDialog != null) {
            prgDialog.dismiss();
        }
        super.onDestroy();
    }
    
    /**
     * Connection with the server
     */
    private WebSocketClient client;
    private JSONUtil jsonUtil;
    @SuppressWarnings("deprecation")
    void startUpClient() {
        if(client != null && client.isConnected()) {
            return;
        }
        jsonUtil = new JSONUtil(getApplicationContext());
        client = new WebSocketClient(URI.create(WsConfig.URL_WEBSOCKET
                + URLEncoder.encode(WsConfig.SESSION_TAG_DEFAULT)), new WebSocketClient.Listener() {
            public void onConnect() {
                
            }
            public void onMessage(String message) {
                parseMessage(message);
            }
            public void onMessage(byte[] data) {
                // Message will be in JSON format
                parseMessage(JSONUtil.bytesToHex(data));
            }
            public void onDisconnect(int code, String reason) {
                String message = String.format(Locale.US,
                        "Disconnected! Code: %d Reason: %s", code, reason);
                showToast(message);
            }
            public void onError(Exception error) {
                showToast("Error! : " + error);
            }
        }, null);
        client.connect();
    }
    
    //remove the null judge for immediately send a message after connection setup
    private void sendRequest(String message) {
        if(client != null && client.isConnected()) {
            client.send(message);
        }
    }
    
    private void parseMessage(final String msg) {
    
        try {
            JSONObject jObj = new JSONObject(msg);
    
            // JSON node 'flag'
            String flag = jObj.getString("flag");
    
            if (flag.equalsIgnoreCase(JSONUtil.FLAG_MESSAGE_GROUP_SETUP)) {
                
                String result = jObj.getString("result");
                showToast(result);
                
                if(result != null && result.equalsIgnoreCase("success")) {
                  //go back to the previous activity
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            finish();
                       }
                    });
                }
                
                // Hide Progress Dialog
                prgDialog.hide();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    
    private void showToast(final String message) {
        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), message,
                        Toast.LENGTH_SHORT).show();
            }
        });
    
    }

}
